package cn.tianyigps.tianyigpsapiv2.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created with IDEA
 * author:guibin.cui
 * Date:2018/5/9
 * Time:14:39
 * 时间判断工具类
 */
@Slf4j
public class TimeUtil {
    /**
     * 判断时间是否在时间段内
     *
     * @param nowTime
     * @param beginTimeStr 格式为 "HH:mm:ss"
     * @param endTimeStr
     * @return
     */
    public static boolean belongCalendar(Date nowTime, String beginTimeStr, String endTimeStr) {
        if (!StringUtils.isEmpty(beginTimeStr) && !StringUtils.isEmpty(endTimeStr)) {

            SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//设置日期格式
            Date now = null;
            Date beginTime = null;
            Date endTime = null;
            try {
                now = df.parse(df.format(nowTime));
                beginTime = df.parse(beginTimeStr);
                endTime = df.parse(endTimeStr);
            } catch (ParseException e) {
                e.printStackTrace();
                log.error("时间转换异常！" + beginTimeStr + " , " + endTimeStr);
                return false;
            }

            Calendar date = Calendar.getInstance();
            date.setTime(now);
            Calendar begin = Calendar.getInstance();
            begin.setTime(beginTime);

            Calendar end = Calendar.getInstance();
            end.setTime(endTime);
            if (date.after(begin) && date.before(end)) {
                return true;
            }
            return false;
        }
        return false;
    }

    /**
     * 获取没有时分秒的日期
     *
     * @param now
     * @return
     */
    public static Date getDateWithoutTime(Date now) {
        if (!Optional.ofNullable(now).isPresent())
            return now;
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(now);
        // 将时分秒,毫秒域清零
        cal1.set(Calendar.HOUR_OF_DAY, 0);
        cal1.set(Calendar.MINUTE, 0);
        cal1.set(Calendar.SECOND, 0);
        cal1.set(Calendar.MILLISECOND, 0);
        return cal1.getTime();
    }
    /**
     * 小时累加(有时分秒)
     *
     * @param now
     * @return
     */
    public static Date getDateAddHour(Date now,int hour) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(now);
        cal1.add(Calendar.HOUR_OF_DAY,hour);
        return cal1.getTime();
    }
    /**
     * 天数累加(有时分秒)
     *
     * @param now
     * @return
     */
    public static Date getDateAddDays(Date now,int days) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(now);
        cal1.add(Calendar.DAY_OF_MONTH,days);
        return cal1.getTime();
    }
    /**
     * 天数累减(有时分秒)
     *
     * @param now
     * @return
     */
    public static Date getDateSubtractDays(Date now,int days) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(now);
        cal1.set(Calendar.DAY_OF_MONTH,cal1.get(Calendar.DATE) - days);
        return cal1.getTime();
    }
    /**
     * 天数累加(无时分秒)
     *
     * @param now
     * @return
     */
    public static Date getDateAddDaysWithoutTime(Date now,int days) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(now);
        cal1.add(Calendar.DAY_OF_MONTH,days);
        Date dateWithoutTime = getDateWithoutTime(cal1.getTime());
        return dateWithoutTime;
    }
    /**
     * 获取到小时的日期
     *
     * @param now
     * @return
     */
    public static Date getDateToHour(Date now) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(now);
        // 将时分秒,毫秒域清零
        cal1.set(Calendar.MINUTE, 0);
        cal1.set(Calendar.SECOND, 0);
        cal1.set(Calendar.MILLISECOND, 0);
        return cal1.getTime();
    }
    /**
     * 比较日期先后
     * @param date1
     * @param date2
     * @return
     */
    public static Boolean judgmentBefore(Date date1,Date date2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);
        return c1.before(c2);
    }

    /**
     * 获取两个时间的分钟差
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static Integer getMins(Date endTime, Date startTime) {

        double d = (endTime.getTime() - startTime.getTime()) / 1000.00 / 60.00;
        return (new Double(Math.ceil(d))).intValue();
    }


    /**
     * @Description: 判断校验时间是否在时间天数的区间当中
     * @params: [startTime, endTime, reportTime]
     * @return: java.lang.Boolean
     * @auther: yangxl
     * @date: 2018/6/28 18:13
     */
    public static Boolean checkDate(Date startTime, Date endTime, Date reportTime) {
        Boolean result = false;
        boolean existBeginDate = false;
        boolean existEndDate = false;
        Date beginDate = null;
        Date endDate = null;
        if (Optional.ofNullable(startTime).isPresent()) {
            //获取校验时间（生效时间和失效时间）
            beginDate = TimeUtil.getDateWithoutTime(startTime);
            existBeginDate = Optional.ofNullable(beginDate).isPresent();
        }
        if (Optional.ofNullable(endTime).isPresent()) {
            endDate = TimeUtil.getDateWithoutTime(endTime);
            existEndDate = Optional.ofNullable(endDate).isPresent();
        }
        //判断生效时间和失效时间都存在的情况
        if (existBeginDate && existEndDate) {
            //判断数据的上报时间是否大于校验开始时间小于校验结束时间
            if (reportTime.after(beginDate) && endDate.after(reportTime)) {
                result = true;
            }
        }
        //生效时间存在但失效时间不存在
        else if (existBeginDate && !existEndDate) {
            if (reportTime.after(beginDate)) {
                result = true;
            }
        }
        //生效时间不存在但失效时间存在
        else if (!existBeginDate && existEndDate) {
            if (endDate.after(reportTime)) {
                result = true;
            }
        }
        //生效时间和失效时间都不存在时
        else if (!existBeginDate && !existEndDate) {
            result = true;
        }
        return result;
    }

    public static int differentDaysByMillisecond(Date date1,Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        return days;
    }
    public static double differentDays(Date date1,Date date2) {

        double ms =  Double.valueOf(date2.getTime()) - Double.valueOf(date1.getTime()) +  0.0000000 ;
        double m  =  1000 * 3600 * 24 + 0.0000000;
        double i = ms / m ;
        return  i ;
    }
    /**返回两个时间之间的 格式为yyyy-MM-dd 的日期集合。
     */
    public static List<String> getDiffDays(Date start, Date end) {

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dateStrs = new ArrayList<>();
        if (!Optional.ofNullable(start).isPresent())
            start = new Date();
        if (!Optional.ofNullable(end).isPresent()){
            Calendar c = Calendar.getInstance();
            c.setTime(new Date());
            c.add(Calendar.SECOND,1);
            end = c.getTime();
        }
        double d = (end.getTime() - start.getTime()) / (1000 * 3600 * 24.00);
        int days = (int) Math.ceil(d);
       for (int i = 1 ; i <= days;i ++){
           Calendar c = Calendar.getInstance();
           c.setTime(start);
           c.add(Calendar.DAY_OF_MONTH,i-1);
           Date time = c.getTime();
           String format = df.format(time);
           dateStrs.add(format);
       }
        return dateStrs;
    }

    /**
     * 获取提供日期的周一  格式化为String类型 yyyyMMdd
     */
    public static String formatString(Date d) {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return format.format(cal.getTime());
    }

    public static String formatString(Date date, SimpleDateFormat format) {
        return format.format(date);
    }

    /**
     * 获取当天十二点或零点的Date类型
     * @param date
     * @param flag
     * @return
     */
    public static Date weeHours(Date date, int flag) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int second = cal.get(Calendar.SECOND);
        // 时分秒（毫秒数）
        long millisecond = hour * 60 * 60 * 1000 + minute * 60 * 1000 + second * 1000;
        // 凌晨00:00:00
        cal.setTimeInMillis(cal.getTimeInMillis() - millisecond);
        if (0 == flag) {
            return cal.getTime();
        } else if (24 == flag) {
            // 凌晨23:59:59
            cal.setTimeInMillis(cal.getTimeInMillis() + 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 59 * 1000);
        }
        return cal.getTime();
    }

    /**
     * 比较是否超过了传入指定时间间隔 true超过 false未超过
     * @param start 开始时间
     * @param end  结束时间
     * @param duration  时长
     * @param unit 时间单位 "H"时"M"分"S"秒,可以扩展天月年等等
     * @return
     */
    public static boolean compareExceedInterval(Date start, Date end, int duration, String unit){
        long time = end.getTime() -start.getTime();
        double result;
        if("SECOND".equals(unit)){
            result = time * 1.0 / 1000;
            return result > duration;
        }
        if("MINUTE".equals(unit)){
            result = time * 1.0 / (1000*60);
            return result > duration;
        }
        if("HOUR".equals(unit)){
            result = time * 1.0 / (1000*60*60);
            return result > duration;
        }
        throw new RuntimeException("服务器异常！");
    }
}
